package com.jswdwsx.esign.service

import com.jswdwsx.esign.cloud.exception.EsignException
import com.jswdwsx.esign.util.Id
import okhttp3.*
import org.apache.commons.io.IOUtils
import org.slf4j.LoggerFactory.getLogger
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.scheduling.annotation.Async
import org.springframework.stereotype.Service
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.util.*


@Service
class DownloadFileService(
    @Qualifier("commonHttpClient")
    private val client: OkHttpClient,
    private val ossToolService: OssToolService
) {

    private val logger = getLogger(DownloadFileService::class.java)

    /**
     * 根据E签宝的下载url，获取文件并转存到我们自己的oss中
     * @param fileName E签宝返回的文件名 即创建文件时的模板名（我们库里的，不是E签宝库里的模板名）
     * @param downloadUrl E签宝提供的下载url
     * @return 我们自己的oss中的文件url
     */
    fun storedFile2Oss(fileName: String, downloadUrl: String): String {
        // OSS 图片转存
        val request = Request.Builder()
            .url(downloadUrl)
            .build()
        val inputStream = client.newCall(request).execute().body?.byteStream() ?: throw EsignException(
            "文件下载失败"
        )

        return ossToolService.updatePic(
            fileName ="${fileName.substringBeforeLast(".pdf")}${Id.FILE.prefix}${UUID.randomUUID()}.pdf",
            bytes = IOUtils.toByteArray(inputStream)
        )
    }

    @Async
    fun download(requestId: String, fileName: String, downloadUrl: String) {
        logger.info("requestId{$requestId}归档文件,url:$downloadUrl")
        val request = Request.Builder()
            .url(downloadUrl)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                logger.error("文件下载失败，requestId：${e.message}", e)
            }

            override fun onResponse(call: Call, response: Response) {
                response.use {
                    if (!response.isSuccessful) throw IOException("Unexpected code $response")

                    writeFile(response, fileName)
                }
            }
        })
    }

    /**
     * 先测试写到本地
     */
    fun writeFile(response: Response, fileName: String) {
        val inputStream: InputStream = response.body?.byteStream() ?: throw EsignException(
            "文件下载失败"
        )
        val fos: FileOutputStream
        val path = "/"
        val file = File(path, fileName)
        try {
            fos = FileOutputStream(file)
            val bytes = ByteArray(1024)

            while ((inputStream.read(bytes)) != -1) {
                fos.write(bytes)
            }
            fos.close()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                inputStream.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
}
